"use strict";

const _ 		= require("lodash");
const appRoot = require('app-root-path');
const CacheCleanerMixin = require(appRoot + "/mixins/cache.cleaner.mixin");
const moment = require('moment');
const Fakerator = require("fakerator");
const fakerator  = new Fakerator();


const mongoMixin = require(appRoot + "/mixins/mongo.mixin");
/**
 * @typedef {import('moleculer').Context} Context Moleculer's Context
 */

module.exports = {
	name: "mongo.member",
	version: 1,
	/**
	 * Mixins
	 */
	mixins:[mongoMixin("member"), CacheCleanerMixin(["cache.clean.member"])],

	/**
	 * Settings
	 */
	settings: {
		auth:"ignore",
		excludeDBService:['create','get','update','remove'],//屏蔽所有框架自动生成的接口
	},


	/**
	 * Actions
	 */
	actions: {


		/**
		 * 将 document 保存到 mongo db 中
		 *
		 */
		createEntity: {
			rest: {
				method: "POST",
				path: "/"
			},
			params:{
				fullName:{ type:"string", trim:true, optional:true },
				firstName:{ type:"string", trim:true, optional:true },
				lastName:{ type:"string", trim:true, optional:true },
				userName:{ type:"string", trim:true, optional:true },
				password:{ type:"string", trim:true, optional:true },
				email:{ type:"email", trim:true,  optional:true},
				phone:{ type:"string", trim:true, optional:true},
				dob:{ type:"string", trim:true,  optional:true},
				website:{ type:"string", trim:true, optional:true},
				ip:{ type:"string", trim:true,  optional:true},
				avatar:{ type:"url", trim:true, optional:true},
				gravatar:{ type:"url",  trim:true, optional:true},
				address:{
					type:"object", props:{
						country:{ type:"string", trim:true, optional:true},
						countryCode:{ type:"string", trim:true, optional:true},
						state:{ type:"string",  trim:true, optional:true},
						street:{ type:"string", trim:true, optional:true },
						zip:{ type:"string",  trim:true, optional:true },
						geo:{
							type:"object", props:{
								latitude:{ type:"number",convert:true, integer:false, optional:false, min: -90, max: 90},
								longitude:{ type:"number",convert:true, integer:false, optional:false, min: -180, max: 180}
							}
						},
					}
				},
				status:{ type:"boolean",  default:true, trim:true, optional:true},
			},
			async handler(ctx) {
				let member = fakerator.entity.user();
				member = Object.assign({fullName:`${member.firstName}.${member.lastName}`},member);
				member = Object.assign(member,ctx.params);
				const doc = await this.adapter.insert(ctx.params);
				member = await this.transformDocuments(ctx, {}, doc);
				await this.entityChanged("created", member, ctx);
				return member;
			}
		},

		updateEntity: {
			rest: "PUT /",
			params: {},
			async handler(ctx) {
				const id = ctx.params._id;
				delete ctx.params._id;
				const update = {
					"$set": ctx.params
				};
				const doc = await this.adapter.updateById(id, update);
				const member = await this.transformDocuments(ctx, {}, doc);
				await this.entityChanged("updated", member, ctx);
				return member;
			}
		},

		deleteEntity: {
			rest: "DELETE /:id",
			params: {
				id:{ type:"string" },
			},
			async handler(ctx) {
				const id = ctx.params._id;
				const doc = await this.adapter.removeById(id);
				const member = await this.transformDocuments(ctx, {}, doc);
				await this.entityChanged("removed", member, ctx);
				return member;
			}
		},

		getEntity:{
			rest: {
				method: "GET",
				path: "/:id"
			},
			params: {
				id:{ type:"string" },
			},
			cache:true,
			async handler(ctx) {
				return this.adapter.findById(ctx.params.id);
			}
		},

	},

	/**
	 * Methods
	 */
	methods: {

	},

	/**
	 * Fired after database connection establishing.
	 */
	async afterConnected() {
		// 初始化测试数据
		const count = await this.adapter.count({});
		if(count < 50){
			await this.adapter.removeMany({});
			let members =  await this.adapter.insertMany(_.times(50, () => {
				let member = fakerator.entity.user();
				member = Object.assign({fullName:`${member.firstName}  ${member.lastName}`},member);
				return member;
			}));
			//this.broker.logger.error(members);
		}

		await this.adapter.collection.createIndex({
			"fullName": "text"
		}, null,(err,result)=>{
			if(err){
				this.logger.error(`Rebuild Index error: ${err}.`);  //TODO: 如果指定集合不存在，则会执行到这
			}
			this.logger.error("Rebuild Index Successfully.");
		});
	}
};
